package com.hwpt.hwaccount.feature.feedback;

import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
import android.util.Log;

import com.hwpt.hwaccount.core.data.local.dao.UserDao;
import com.hwpt.hwaccount.core.data.local.entity.ImageMetaData;
import com.hwpt.hwaccount.core.data.local.entity.UserEntity;
import com.hwpt.hwaccount.core.data.remote.RetrofitClient;
import com.hwpt.hwaccount.core.data.remote.api.ApiService;
import com.hwpt.hwaccount.core.data.remote.request.FeedbackRequest;
import com.hwpt.hwaccount.core.data.repository.UserInfoRepository;
import com.hwpt.hwaccount.core.utils.ImageMetaDataUtil;
import com.hwpt.hwaccount.core.utils.NetworkResponseHandler;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.schedulers.Schedulers;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;

public class FeedbackModel implements FeedbackContract.Model {
    
    private static final String TAG = "FeedbackModel";
    
    private Context context;
    private ImageMetaDataUtil imageMetaDataUtil;
    private ApiService apiService;
    private UserDao userDao;
    private CompositeDisposable disposables;
    private  UserInfoRepository repository;


    public FeedbackModel(Context context, ApiService apiService, UserDao userDao) {
        this.context = context.getApplicationContext();
        this.imageMetaDataUtil = new ImageMetaDataUtil(context);
        this.apiService = RetrofitClient.getApiService(this.context);
        this.userDao = userDao;
        this.disposables = new CompositeDisposable();
        this.repository = new UserInfoRepository(context);
    }
    
    @Override
    public List<FeedbackType> loadFeedbackTypes() {
        List<FeedbackType> feedbackTypes = new ArrayList<>();
        
        // 硬件与外观
        feedbackTypes.add(new FeedbackType("硬件与外观", ""));
        feedbackTypes.add(new FeedbackType("平板外观容易磨损/刮花", "硬件与外观"));
        feedbackTypes.add(new FeedbackType("平板没有摄像头", "硬件与外观"));
        feedbackTypes.add(new FeedbackType("屏幕易划伤/易留指纹", "硬件与外观"));
        feedbackTypes.add(new FeedbackType("按键或接口松动", "硬件与外观"));
        feedbackTypes.add(new FeedbackType("充电慢或充电口接触不良", "硬件与外观"));
        feedbackTypes.add(new FeedbackType("电磁笔不灵敏/压力感不准确/手写延迟", "硬件与外观"));
        feedbackTypes.add(new FeedbackType("电池续航不足 / 电量显示不准确", "硬件与外观"));
        
        // 性能与存储
        feedbackTypes.add(new FeedbackType("性能与存储", ""));
        feedbackTypes.add(new FeedbackType("内存不够用 / 存储空间不足", "性能与存储"));
        feedbackTypes.add(new FeedbackType("系统运行卡顿 / 打开应用慢", "性能与存储"));
        feedbackTypes.add(new FeedbackType("多任务切换体验差", "性能与存储"));
        feedbackTypes.add(new FeedbackType("发热明显", "性能与存储"));
        feedbackTypes.add(new FeedbackType("音量或扬声器效果差", "性能与存储"));
        feedbackTypes.add(new FeedbackType("屏幕亮度或色彩不理想", "性能与存储"));
        
        // 软件与功能
        feedbackTypes.add(new FeedbackType("软件与功能", ""));
        feedbackTypes.add(new FeedbackType("生态不完善 / 应用兼容性差", "软件与功能"));
        feedbackTypes.add(new FeedbackType("系统功能不够完整（如缺少云同步）", "软件与功能"));
        feedbackTypes.add(new FeedbackType("平板定位或网络功能不稳定", "软件与功能"));
        feedbackTypes.add(new FeedbackType("多语言或输入法支持不够", "软件与功能"));
        
        feedbackTypes.add(new FeedbackType("其他问题", ""));
        
        return feedbackTypes;
    }
    
    @Override
    public boolean validateFeedback(String type, String description) {
        if ("请选择问题类型".equals(type)) {
            return false;
        }
        
        if (description == null || description.isEmpty()) {
            return false;
        }
        
        return true;
    }

    @Override
    public void submitFeedback(String type, String description, String phone, List<Uri> images, OnSubmitCallback callback) {
        // 首先从Room数据库获取用户token
        disposables.add(repository.getAllUsers()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(users -> {
                    if (users != null && !users.isEmpty()) {
                        UserEntity user = users.get(0);
                        String token = user.getToken();
                        String hanWangId = user.getHanWangId();

                        if (token == null || token.isEmpty()) {
                            callback.onError("用户未登录，请先登录");
                            return;
                        }

                        // 创建图片元数据列表
                        List<ImageMetaData> imageMetaDataList = new ArrayList<>();

                        if (images != null && !images.isEmpty()) {
                            for (Uri imageUri : images) {
                                ImageMetaData metaData = imageMetaDataUtil.getImageMetaData(imageUri);
                                if (metaData != null) {
                                    imageMetaDataList.add(metaData);
                                }
                            }
                        }

                        // 创建反馈请求对象
                        FeedbackRequest request = new FeedbackRequest(hanWangId, type, description, phone, imageMetaDataList, token);
                        Log.d(TAG, "submitFeedback: " + request.toString());

                        // 使用 List<String> 作为泛型类型
                        NetworkResponseHandler.handleResponse(
                                apiService.submitFeedback(request),
                                new NetworkResponseHandler.ResponseCallback<List<String>>() {
                                    @Override
                                    public void onSuccess(List<String> presignedUrls) {
                                        Log.d(TAG, "获取到预签名URL列表: " + presignedUrls);

                                        if (presignedUrls == null || presignedUrls.isEmpty()) {
                                            callback.onError("未获取到有效的上传URL");
                                            return;
                                        }

                                        if (presignedUrls.size() != images.size()) {
                                            Log.w(TAG, "URL数量与图片数量不匹配: URLs=" + presignedUrls.size() + ", Images=" + images.size());
                                        }

                                        // 上传图片到MinIO
                                        uploadImagesToMinIO(images, presignedUrls, callback);
                                    }

                                    @Override
                                    public void onFailure(String errorMsg) {
                                        callback.onError(errorMsg);
                                    }
                                }
                        );

                    } else {
                        callback.onError("用户信息不存在，请先登录");
                    }
                }, throwable -> {
                    callback.onError("获取用户信息失败: " + throwable.getMessage());
                }));
    }

    /**
     * 上传图片到MinIO
     */
    private void uploadImagesToMinIO(List<Uri> imageUris, List<String> presignedUrls, OnSubmitCallback callback) {
        List<String> uploadedUrls = new ArrayList<>();
        AtomicInteger uploadCount = new AtomicInteger(0);
        int totalCount = Math.min(imageUris.size(), presignedUrls.size());

        if (totalCount == 0) {
            callback.onSuccess(new ArrayList<>());
            return;
        }

        for (int i = 0; i < totalCount; i++) {
            Uri imageUri = imageUris.get(i);
            String presignedUrl = presignedUrls.get(i);

            int finalI = i;
            uploadImageToMinIO(imageUri, presignedUrl, new MinIOUploadCallback() {
                @Override
                public void onSuccess(String imageUrl) {
                    uploadedUrls.add(imageUrl);
                    Log.d(TAG, "图片 " + (finalI + 1) + " 上传成功: " + imageUrl);

                    if (uploadCount.incrementAndGet() == totalCount) {
                        // 所有图片都上传完成
                        callback.onSuccess(uploadedUrls);
                    }
                }

                @Override
                public void onFailure(String errorMsg) {
                    Log.e(TAG, "图片 " + (finalI + 1) + " 上传失败: " + errorMsg);

                    if (uploadCount.incrementAndGet() == totalCount) {
                        // 即使有失败，也返回已成功的URL列表
                        if (uploadedUrls.isEmpty()) {
                            callback.onError("所有图片上传失败");
                        } else {
                            callback.onSuccess(uploadedUrls);
                        }
                    }
                }
            });
        }
    }

    /**
     * 单张图片上传到MinIO
     */
    private void uploadImageToMinIO(Uri imageUri, String presignedUrl, MinIOUploadCallback callback) {
        // 使用ContentResolver读取文件内容
        try {
            ContentResolver contentResolver = context.getContentResolver();
            InputStream inputStream = contentResolver.openInputStream(imageUri);

            if (inputStream == null) {
                callback.onFailure("无法打开文件流");
                return;
            }

            // 将InputStream读取为字节数组
            byte[] fileBytes = readInputStreamToByteArray(inputStream);
            inputStream.close();

            RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), fileBytes);

            Request request = new Request.Builder()
                    .url(presignedUrl)
                    .put(requestBody)
                    .build();

            OkHttpClient client = new OkHttpClient();
            client.newCall(request).enqueue(new okhttp3.Callback() {
                @Override
                public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
                    if (response.isSuccessful()) {
                        // 上传成功，返回的URL就是presignedUrl去掉查询参数的部分
                        String uploadedUrl = presignedUrl.split("\\?")[0];
                        callback.onSuccess(uploadedUrl);
                    } else {
                        callback.onFailure("上传失败: " + response.code() + " - " + response.message());
                    }
                    response.close();
                }

                @Override
                public void onFailure(okhttp3.Call call, IOException e) {
                    callback.onFailure("网络错误: " + e.getMessage());
                }
            });
        } catch (Exception e) {
            callback.onFailure("上传异常: " + e.getMessage());
        }
    }

    /**
     * 将InputStream转换为字节数组
     */
    private byte[] readInputStreamToByteArray(InputStream inputStream) throws IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int nRead;
        byte[] data = new byte[16384]; // 16KB缓冲区

        while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
        }

        return buffer.toByteArray();
    }

    interface MinIOUploadCallback {
        void onSuccess(String imageUrl);
        void onFailure(String errorMsg);
    }
    /**
     * 清理资源
     */
    public void dispose() {
        if (disposables != null && !disposables.isDisposed()) {
            disposables.dispose();
        }
    }
    
    public static class FeedbackType {
        private String name;
        private String category;
        
        public FeedbackType(String name, String category) {
            this.name = name;
            this.category = category;
        }
        
        public String getName() {
            return name;
        }
        
        public String getCategory() {
            return category;
        }
    }
}